package com.rao.gmall.order.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rao.gmall.common.result.Result;
import com.rao.gmall.common.result.ResultCodeEnum;
import com.rao.gmall.common.util.AuthContextHolder;
import com.rao.gmall.model.enums.OrderStatus;
import com.rao.gmall.model.order.OrderDetail;
import com.rao.gmall.model.order.OrderInfo;
import com.rao.gmall.order.service.OrderDetailService;
import com.rao.gmall.order.service.OrderInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @author nzmxfan
 * @create 2021-08-20-19:37
 */
@RestController
@RequestMapping("/api/order")
public class OrderInfoController {

    @Autowired
    OrderInfoService orderInfoService;

    @Autowired
    OrderDetailService orderDetailService;

    /**
     * 提交订单
     * @param tradeNo
     */
    @PostMapping("/auth/submitOrder")
    public Result submitOrder(@RequestParam(value = "tradeNo", required = true) String tradeNo,
                            @RequestBody OrderInfo orderInfo,
                            HttpServletRequest request){


        String userId = AuthContextHolder.getUserId(request); // userId = null
        // 1.验证令牌 tradeNo
        if (!orderInfoService.checkToken(userId, tradeNo)){
            // 不合法
            return Result.build(null, ResultCodeEnum.REPEAT_SUBMIT);
        }

        // 声明一个变量，将验库存、验价所有异常收集，统一返回给前端
        List<String> errMsg = orderInfoService.checkSkuPriceAndStock(orderInfo.getOrderDetailList());

        if (!CollectionUtils.isEmpty(errMsg)){
            // 前面的验证失败
            Result<Object> fail = Result.fail();
            // 将集合的元素通过 逗号拼接起来
            String join = String.join(",", errMsg);
            fail.setMessage(join);
            return fail;
        }

        //验库存（基于我们不允许超卖）；确保当前订单的商品库存是有的，
        //feign接口已经有了。挨个验证是否有货
        //锁库存 【下单锁(X)，支付成功锁(V)】
        //哪些商品的价格发生变动，让前端重新确认（页面刷新一下，显示新价格，如果用户接受就继续提交）
        //哪些商品没有库存，要提示用户从购物车中自己移除没有库存的商品
        // 基本上电商都是允许超卖【秒杀】。 （想的不是解决超卖，而是解决供应链）
        // 超出数量以后（供应链速度快的）  一件代发，第二天发货就行
        // 正常订单允许超卖


        // 验价;  把前端提交来得订单价格和当前商品真的价格进行比对。
        // 一样，正常下单。不一样，返回失败，并提示哪个商品价格有变化



        // 3.创建订单
        // 将用于信息加入到订单信息中
        orderInfo.setUserId(Long.parseLong(userId));

        OrderInfo createOrder = orderInfoService.createOrder(orderInfo);
        Long id = createOrder.getId();

        return Result.ok(id);
    }

//    /**
//     * 根据 outTradeNo 查询订单信息
//     * @param outTradeNo 外部流水号（供第三方服务使用）
//     * @return
//     */
//    @GetMapping("/payed/success")
//    public OrderInfo getOrderInfo(@RequestParam("outTradeNo") String outTradeNo){
//        // 设置查询条件
//        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
//        wrapper.eq("out_trade_no", outTradeNo);
//        return orderInfoService.getOne(wrapper);
//    }

    @GetMapping("/getorder/{id}")
    public OrderInfo getOrderInfo(@PathVariable("id") Long orderId){
        return orderInfoService.getById(orderId);
    }

    @GetMapping("/pay/success")
    public void changeOrderStatusPayed(String outTradeNo){
        orderInfoService.changeOrderStatusPayed(outTradeNo, OrderStatus.PAID.name());
    }

    @GetMapping("/auth/{pageNo}/{pageSize}")
    public Result getOrdersByPage(@PathVariable("pageNo") Integer pageNo,
                                  @PathVariable("pageSize") Integer pageSize,
                                  HttpServletRequest request){

        String userId = AuthContextHolder.getUserId(request);

        IPage<OrderInfo> page = new Page<>(pageNo, pageSize);

        QueryWrapper<OrderInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.orderByDesc("id");

        IPage<OrderInfo> infoIPage = orderInfoService.page(page, wrapper);
        List<OrderInfo> records = infoIPage.getRecords();
        for (OrderInfo record : records) {
            QueryWrapper<OrderDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("order_id", record.getId());
            List<OrderDetail> list = orderDetailService.list(queryWrapper);
            record.setOrderDetailList(list);
        }

        return Result.ok(infoIPage);
    }
}
